// 定义数据搬运引擎
tops_dte_ctx_t ctxs[2][2];
// 定义事件
tops::event evs[2][2];

// 初始化数据搬运引擎
for(int i = 0; i < 2; i++)
{
    for(int j = 0; j < 2; j++)
    {
        ctxs[i][j].init();
    }
}

// 定义l1缓存
__valigned__ int input_buffer[2][tile_size];
__valigned__ int output_buffer[2][tile_size];

// 绑定地址,利用接口搬运数据需要使用mdspan数据结构
tops::mdspan input(tops::Global, in, tile_size)// in为L3的数据输入地址的指针

tops::mdspan output(tops::Global, out, tile_size)// out为L3的数据输出地址的指针

// 全量配置数据搬运引擎
for(int i = 0; i < 2; i++) // L3 -> L1
{
    ctxs[0][i].config_memcpy(tops::mdspan(tops::Private, input_buffer[i], tile_size), input, tile_size);
}

for(int i = 0; i < 2; i++) // L1 -> L3
{
    ctxs[1][i].config_memcpy(output, tops::mdspan(tops::Private, output_buffer[i], tile_size), tile_size);
}

evs[0][0] = ctxs[0][0].trigger();
int iter = 0;

for(int i = 0; i < size; i += tile_size)
{
    evs[0][iter%2].wait();

    if(i + tile_size < size)
    {
        ctxs[0][(iter + 1) % 2].set_src_addr(in + i);
        evs[0][(iter + 1) % 2] = ctxs[0][(iter + 1) % 2].trigger();
    }

    // 计算
    foo(input_buffer[iter%2], output_buffer[iter%2]);
    // tops::wait(foo)

    if(i != 0)
    {
        evs[1][(iter - 1) % 2].wait();
    }

    // 输出
    ctxs[1][iter%2].set_dst_addr(out + i);
    evs[1][iter%2] = ctxs[1][iter%2].trigger();

    
    if(i + tile_size >= size)
    {
        evs[1][iter % 2].wait();
    }
    iter++;
}

//销毁数据搬运引擎
for(int i = 0; i < 2; i++)
{
    for(int j = 0; j < 2; j++)
    {
        ctxs[i][j].destroy();
    }
}

